﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.IO;
using System.Text;
using System.Windows.Forms;

using Storm.TextEditor.Core;
using Storm.TextEditor.Core.Splitting;
using Storm.TextEditor.Editor;
using Storm.TextEditor.Editor.CodeCompletion;
using Storm.TextEditor.Editor.Interacting;
using Storm.TextEditor.Editor.Text;
using Storm.TextEditor.Interacting;
using Storm.TextEditor.Interacting.Keyboard;
using Storm.TextEditor.Languages;
using Storm.TextEditor.Parser;
using Storm.TextEditor.Parser.Objects;
using Storm.TextEditor.Parser.Objects.Collections;
using Storm.TextEditor.Parser.XML;
using Storm.TextEditor.Win32.Enums;

namespace Storm.TextEditor
{
	/// <summary>
	/// Represents a text editor control that has features such as syntax highlighting, line numbers, bookmarks, and more.
	/// </summary>
	[ToolboxItem(true)]
	[Description("Represents a text editor control that has features such as syntax highlighting, line numbers, bookmarks, and more.")]
	public class TextEditor
		: Widget
	{
		#region Fields

		protected internal readonly bool DisableScrollHandler	= false;
		protected internal readonly bool DisableFindForm		= false;
		protected internal readonly bool DisableAutoList		= false;
		protected internal readonly bool DisableSplitView		= false;
		protected internal readonly bool DisableScrollBars		= false;

		private int tooltipDelay		= 240;
		private int tabSize				= 4;
		private int gutterMarginWidth	= 15;
		private int smoothScrollSpeed	= 2;
		private int rowPadding			= 0;

		private long  ticks    = 0;
		private float fontSize = 10f;

		private bool showWhitespace		= false;
		private bool showTabGuides		= false;
		private bool showEOLMarker		= false;
		private bool showScopeIndicator = true;
		private bool showLineNumbers	= true;
		private bool showGutterMargin	= true;

		private bool highlightActiveLine	= false;
		private bool virtualWhitespace		= false;
		private bool useDottedMarginBorder  = false;
		private bool bracketMatching		= true;

		private bool parseOnPaste = false;
		private bool smoothScroll = false;

		private bool allowBreakPoints	= true;
		private bool splitView			= true;
		private bool createdSplitViews	= false;
		private bool saved				= false;
		private bool readOnly			= false;
		private bool lockCursorUpdate	= false;
		private bool copyAsRTF			= false;
		private bool tooltipShown		= false;

		private bool bracketBold			= false;
		private bool bracketItalic			= false;
		private bool bracketUnderline		= false;
		private bool bracketStrikethrough	= false;

		private string fileName = "";
		private string fontName = "Consolas";

		private IContainer     components	= null;
		private ScrollBars     scrollBars	= ScrollBars.Both;
		private ArrayList      views		= null;
		private SyntaxDocument document		= null;
		private ToolTip        tooltip		= null;

		private Color backColor				   = SystemColors.Window;
		private Color outlineColor			   = SystemColors.ControlDark;
		private Color collapsedBackgroundColor = Color.FromArgb(226, 226, 226);
		private Color expansionSymbolColor     = Color.FromArgb(85, 85, 85);
		private Color expansionBackgroundColor = Color.FromArgb(235, 238, 244);
		private Color whitespaceColor		   = SystemColors.ControlDark;
		private Color separatorColor		   = SystemColors.Control;
		private Color highlightedLineColor	   = ControlPaint.LightLight(Color.LightBlue);

		private Color gutterMarginColor	= Color.FromArgb(240, 240, 240);

		private Color eolMarkerColor	= Color.ForestGreen;
		private Color tabGuideColor		= ControlPaint.Light(SystemColors.ControlLight);

		private Color rowHoverBackColor   = Color.FromArgb(246, 247, 250);
		private Color breakpointBackColor = Color.DarkRed;
		private Color breakpointForeColor = Color.White;

		private Color lineNumberForeColor	= Color.FromArgb(43, 145, 175);
		private Color lineNumberBorderColor	= Color.FromArgb(43, 145, 175);
		private Color lineNumberBackColor	= SystemColors.Window;

		private Color bracketForeColor		= Color.Black;
		private Color bracketBackColor		= Color.FromArgb(219, 224, 204);
		private Color bracketBorderColor	= Color.Transparent;

		private Color scopeBackColor		= Color.Transparent;
		private Color scopeIndicatorColor	= Color.Transparent;

		private Color selectionBackColor   = Color.FromArgb(173, 214, 255);
		private Color selectionBorderColor = Color.FromArgb(214, 235, 255);

		private Color inactiveSelectionBackColor   = Color.FromArgb(229, 235, 241);
		private Color inactiveSelectionBorderColor = Color.FromArgb(242, 245, 248);

		private TextDrawType       textDrawStyle	= TextDrawType.StarBorder;
		private IndentStyle        indent			= IndentStyle.Scope;
		private TextEditorBase     activeView		= null;
		private KeyboardActionList keyboardActions	= new KeyboardActionList();

		private static Dictionary<string, WordData> wordDatabase = new Dictionary<string, WordData>();

		private TextEditorBase upperLeft  = null;
		private TextEditorBase upperRight = null;
		private TextEditorBase lowerLeft  = null;
		private TextEditorBase lowerRight = null;

		private SplitViewControl splitViewControl	= null;
		private WeakTimer        parseTimer			= null;
		private ImageList        gutterIcons		= null;

		private bool        automaticLanguageDetection = true;
		private XmlLanguage currentLanguage            = XmlLanguage.None;

		#region Events

		/// <summary>
		/// Occurs when [file name changed].
		/// </summary>
		public event EventHandler FileNameChanged = null;

		/// <summary>
		/// Occurs when [file saved changed].
		/// </summary>
		public event EventHandler FileSavedChanged = null;

		/// <summary>
		/// Occurs when [word mouse hover].
		/// </summary>
		public event WordMouseHandler WordMouseHover = null;

		/// <summary>
		/// Occurs when [word mouse down].
		/// </summary>
		public event WordMouseHandler WordMouseDown = null;

		/// <summary>
		/// Occurs when [clipboard updated].
		/// </summary>
		public event CopyHandler ClipboardUpdated = null;

		/// <summary>
		/// Occurs when [caret change].
		/// </summary>
		public event EventHandler CaretChange = null;

		/// <summary>
		/// Occurs when [selection change].
		/// </summary>
		public event EventHandler SelectionChange = null;

		/// <summary>
		/// Occurs when [render row].
		/// </summary>
		public event RowPaintHandler RenderRow = null;

		/// <summary>
		/// Occurs when [row mouse down].
		/// </summary>
		public event RowMouseHandler RowMouseDown = null;

		/// <summary>
		/// Occurs when [row mouse move].
		/// </summary>
		public event RowMouseHandler RowMouseMove = null;

		/// <summary>
		/// Occurs when [row mouse up].
		/// </summary>
		public event RowMouseHandler RowMouseUp = null;

		/// <summary>
		/// Occurs when [row click].
		/// </summary>
		public event RowMouseHandler RowClick = null;

		/// <summary>
		/// Occurs when [row double click].
		/// </summary>
		public event RowMouseHandler RowDoubleClick = null;

		#endregion

		#endregion

		#region Properties

		/// <summary>
		/// Gets or sets the color to use when rendering a row's expansion's inner symbol. (-/+)
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color to use when rendering a row's expansion's inner symbol. (-/+)")]
		public Color ExpansionSymbolColor
		{
			get { return expansionSymbolColor; }
			set
			{
				expansionSymbolColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color to use when rendering an expansion's background color.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color to use when rendering an expansion's background color.")]
		public Color ExpansionBackgroundColor
		{
			get { return expansionBackgroundColor; }
			set
			{
				expansionBackgroundColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color to use when rendering a hovered row.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color to use when rendering a hovered row.")]
		public Color RowHoverBackColor
		{
			get { return rowHoverBackColor; }
			set
			{
				rowHoverBackColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether to keep tabs or replace them with spaces when indenting.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets whether to keep tabs or replace them with spaces when indenting.")]
		public bool KeepTabs
		{
			get { return activeView.KeepTabs; }
			set { activeView.KeepTabs = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the TextEditor should use a dotted margin border.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if the TextEditor should use a dotted margin border; otherwise, <c>false</c>.
		/// </value>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets a value indicating whether the TextEditor should use a dotted margin border.")]
		public bool UseDottedMarginBorder
		{
			get { return useDottedMarginBorder; }
			set { useDottedMarginBorder = value; }
		}

		/// <summary>
		/// Gets or sets the filename of the currently open file.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets or sets the filename of the currently open file.")]
		public string FileName
		{
			get { return fileName; }
			set { fileName = value; }
		}

		/// <summary>
		/// Gets the active text editor base.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets the active text editor base.")]
		public TextEditorBase ActiveViewControl
		{
			get { return activeView; }
		}

		/// <summary>
		/// Gets or sets whether the current file is saved.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets or sets whether the current file is saved.")]
		public bool Saved
		{
			get { return saved; }
			set
			{
				saved = value;
				this.OnFileSavedChanged(EventArgs.Empty);
			}
		}

		/// <summary>
		/// Gets or sets whether a ¶ should be displayed at the end of a line.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether a ¶ should be displayed at the end of a line.")]
		public bool ShowEOLMarker
		{
			get { return showEOLMarker; }
			set
			{
				showEOLMarker = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color of the EOL markers.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color of the EOL markers.")]
		public Color EOLMarkerColor
		{
			get { return eolMarkerColor; }
			set
			{
				eolMarkerColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the copy actions should be stored as RTF.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets whether the copy actions should be stored as RTF.")]
		public bool CopyAsRTF
		{
			get { return copyAsRTF; }
			set { copyAsRTF = value; }
		}

		/// <summary>
		/// Gets the caret control that the TextEditor is using.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets the caret control that the TextEditor is using.")]
		public Caret Caret
		{
			get
			{
				if (activeView != null)
					return activeView.Caret;

				return null;
			}
		}
		
		/// <summary>
		/// Gets or sets the list of views.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets or sets the list of views.")]
		private ArrayList Views
		{
			get { return views; }
			set { views = value; }
		}

		/// <summary>
		/// Gets or sets the font of the TextEditor.
		/// </summary>
		[Browsable(false)]
		[Category("Appearance")]
		[Description("Gets or sets the font of the TextEditor.")]
		[Obsolete("Use .FontName and .FontSize", true)]
		public new Font Font
		{
			get { return base.Font; }
			set { base.Font = value; }
		}

		/// <summary>
		/// Gets or sets the ForeColor of the TextEditor.
		/// </summary>
		[Browsable(false)]
		[Category("Appearance")]
		[Description("Gets or sets the ForeColor of the TextEditor.")]
		[Obsolete("Apply a syntax highlighting language instead.", true)]
		public new Color ForeColor
		{
			get { return base.ForeColor; }
			set { base.ForeColor = value; }
		}

		/// <summary>
		/// Gets or sets the color of scopes.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color of scopes.")]
		public Color ScopeBackColor
		{
			get { return scopeBackColor; }
			set
			{
				scopeBackColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color of a scope indicator.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color of a scope indicator.")]
		public Color ScopeIndicatorColor
		{
			get { return scopeIndicatorColor; }
			set
			{
				scopeIndicatorColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether a scope indicator is shown.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether a scope indicator is shown.")]
		public bool ShowScopeIndicator
		{
			get { return showScopeIndicator; }
			set
			{
				showScopeIndicator = value;
				Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the distance, in pixels, between the vertical left edge of the control and the vertical left edge of its container's client area.
		/// </summary>
		[Browsable(false)]
		[Category("Appearance")]
		[Description("Gets or sets the distance, in pixels, between the vertical left edge of the control and the vertical left edge of its container's client area.")]
		public int SplitViewVerticalEdgeDistance
		{
			get { return splitViewControl.VerticalEdgeDistance; }
			set
			{
				if (splitViewControl == null)
					return;

				splitViewControl.VerticalEdgeDistance = value;
			}
		}

		/// <summary>
		/// Gets or sets the distance, in pixels, between the horizontal top edge of the control and the horiontal top edge of its container's client area.
		/// </summary>
		[Browsable(false)]
		[Category("Appearance")]
		[Description("Gets or sets the distance, in pixels, between the horizontal top edge of the control and the horiontal top edge of its container's client area.")]
		public int SplitViewHorizontalEdgeDistance
		{
			get { return splitViewControl.HorizontalEdgeDistance; }
			set
			{
				if (splitViewControl == null)
					return;

				splitViewControl.HorizontalEdgeDistance = value;
			}
		}

		/// <summary>
		/// Gets or sets the active view control.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets or sets the active view control.")]
		public ActiveView ActiveView
		{
			get
			{
				if (activeView == upperLeft)
					return ActiveView.TopLeft;

				if (activeView == upperRight)
					return ActiveView.TopRight;

				if (activeView == lowerLeft)
					return ActiveView.BottomLeft;

				if (activeView == lowerRight)
					return ActiveView.BottomRight;

				return (ActiveView)0;
			}
			set
			{
				if (value != ActiveView.BottomRight)
					this.ActivateSplits();

				if (value == ActiveView.TopLeft)
					activeView = upperLeft;

				if (value == ActiveView.TopRight)
					activeView = upperRight;

				if (value == ActiveView.BottomLeft)
					activeView = lowerLeft;

				if (value == ActiveView.BottomRight)
					activeView = lowerRight;
			}
		}

		/// <summary>
		/// Gets or sets whether the control should prevent changing the cursor.
		/// </summary>
		[Browsable(false)]
		[Category("Appearance")]
		[Description("Gets or sets whether the control should prevent changing the cursor.")]
		public bool LockCursorUpdate
		{
			get { return lockCursorUpdate; }
			set { lockCursorUpdate = value; }
		}

		/// <summary>
		/// Gets or sets the row padding in pixels.
		/// </summary>
		[Browsable(false)]
		[Category("Appearance")]
		[Description("Gets or sets the row padding in pixels.")]
		public int RowPadding
		{
			get { return rowPadding; }
			set { rowPadding = value; }
		}

		/// <summary>
		/// Gets the current selection of the active view.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets the current selection of the active view.")]
		public Selection Selection
		{
			get
			{
				if (activeView != null)
					return activeView.Selection;

				return null;
			}
		}

		/// <summary>
		/// Gets or sets the collection of KeyboardActions that is used by the control.
		/// </summary>
		[Browsable(false)]
		[Category("Behaviour")]
		[Description("Gets or sets the collection of KeyboardActions that is used by the control.")]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public KeyboardActionList KeyboardActions
		{
			get { return keyboardActions; }
			set { keyboardActions = value; }
		}

		/// <summary>
		/// Gets whether the control can perform a copy action.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets whether the control can perform a copy action.")]
		public bool CanCopy
		{
			get { return activeView.CanCopy; }
		}

		/// <summary>
		/// Gets whether the control can perform a paste action.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets whether the control can perform a paste action.")]
		public bool CanPaste
		{
			get { return activeView.CanPaste; }
		}

		/// <summary>
		/// Gets whether the control can perform a redo action.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets whether the control can perform a redo action.")]
		public bool CanRedo
		{
			get { return activeView.CanRedo; }
		}

		/// <summary>
		/// Gets whether the control can perform an undo action.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets whether the control can perform an undo action.")]
		public bool CanUndo
		{
			get { return activeView.CanUndo; }
		}

		/// <summary>
		/// Gets or sets the ImageList to use in the gutter margin.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the ImageList to use in the gutter margin.")]
		public ImageList GutterIcons
		{
			get { return gutterIcons; }
			set
			{
				gutterIcons = value;
				this.Redraw();
			}

		}

		/// <summary>
		/// Gets or sets the BorderStyles of the child TextEditorBase controls.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the BorderStyles of the child TextEditorBase controls.")]
		[DefaultValue(ControlBorderStyle.FixedSingle)]
		public ControlBorderStyle ChildBorderStyle
		{
			get { return (this.Views[0] as TextEditorBase).BorderStyle; }
			set
			{
				foreach (TextEditorBase textEditorBase in this.Views)
					textEditorBase.BorderStyle = value;
			}
		}

		/// <summary>
		/// Gets or sets the border color of the child TextEditorBase controls.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the border color of the child TextEditorBase controls.")]
		[DefaultValue(typeof(Color), "ControlDark")]
		public Color ChildBorderColor
		{
			get { return (this.Views[0] as TextEditorBase).BorderColor; }
			set
			{
				foreach (TextEditorBase textEditorBase in this.Views)
					textEditorBase.BorderColor = value;
			}
		}

		/// <summary>
		/// Gets or sets the color to use when rendering Tab Guides.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color to use when rendering Tab Guides.")]
		[DefaultValue(typeof(Color), "Control")]
		public Color TabGuideColor
		{
			get { return tabGuideColor; }
			set
			{
				tabGuideColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color of the bracket match borders when they're highlighted.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color of the bracket match borders when they're highlighted.")]
		[DefaultValue(typeof(Color), "DarkBlue")]
		public Color BracketBorderColor
		{
			get { return bracketBorderColor; }
			set
			{
				bracketBorderColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the control should render Tab Guides.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether the control should render Tab Guides.")]
		[DefaultValue(false)]
		public bool ShowTabGuides
		{
			get { return showTabGuides; }
			set
			{
				showTabGuides = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color to use when rendering a collapsed expansion's background.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color to use when rendering a collapsed expansion's background.")]
		public Color CollapsedBackgroundColor
		{
			get { return collapsedBackgroundColor; }
			set
			{
				collapsedBackgroundColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color to use when rendering whitespace characters.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color to use when rendering whitespace characters.")]
		[DefaultValue(typeof(Color), "Control")]
		public Color WhitespaceColor
		{
			get { return whitespaceColor; }
			set
			{
				whitespaceColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color of the code folding blocks.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color of the code folding blocks.")]
		[DefaultValue(typeof(Color), "ControlDark")]
		public Color OutlineColor
		{
			get { return outlineColor; }
			set
			{
				outlineColor = value;
				this.InitGraphics();
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the control should use a smooth scroll when scrolling.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets whether the control should use a smooth scroll when scrolling.")]
		[DefaultValue(typeof(Color), "False")]
		public bool SmoothScroll
		{
			get { return smoothScroll; }
			set { smoothScroll = value; }
		}

		/// <summary>
		/// Gets or sets the speed of the vertical scroll when SmoothScroll equals true.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets the speed of the vertical scroll when SmoothScroll equals true.")]
		[DefaultValue(2)]
		public int SmoothScrollSpeed
		{
			get { return smoothScrollSpeed; }
			set
			{
				if (value < 1)
					throw (new Exception("value may not be less than 1. Actual value was: " + value));
				else
					smoothScrollSpeed = value;
			}
		}

		/// <summary>
		/// Gets or sets whether breakpoints are enabled.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets whether breakpoints are enabled.")]
		[DefaultValue(true)]
		public bool AllowBreakPoints
		{
			get { return allowBreakPoints; }
			set { allowBreakPoints = value; }
		}

		/// <summary>
		/// Gets or sets whether the control should reparse everything when text is dragged onto the control or pasted into it.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets whether the control should reparse everything when text is dragged onto the control or pasted into it.")]
		[DefaultValue(true)]
		public bool ParseOnPaste
		{
			get { return parseOnPaste; }
			set
			{
				parseOnPaste = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets whether the control is in overwrite mode.
		/// </summary>
		[Browsable(false)]
		[Category("Data")]
		[Description("Gets whether the control is in overwrite mode.")]
		public bool OverWrite
		{
			get { return activeView.OverWrite; }
		}

		/// <summary>
		/// Gets the code completion window.
		/// </summary>
		/// <value>The code completion window.</value>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets the code completion window.")]
		public CodeCompletionWindow CodeCompletionWindow
		{
			get { return activeView.CodeCompletionWindow; }
		}

		/// <summary>
		/// Gets or sets the size of the font.
		/// </summary>
		[Category("Appearance")]
		[Description("Gets or sets the size of the font.")]
		[DefaultValue(10f)]
		public float FontSize
		{
			get { return fontSize; }
			set
			{
				fontSize = value;
				this.InitGraphics();
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets what IndentStyle to use when the user adds a new line.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets what IndentStyle to use when the user adds a new line.")]
		[DefaultValue(IndentStyle.Scope)]
		public IndentStyle Indent
		{
			get { return indent; }
			set { indent = value; }
		}

		/// <summary>
		/// Gets or sets the SyntaxDocument that the control is currently attached to.
		/// </summary>
		[Browsable(true)]
		[Category("Content")]
		[Description("Gets or sets the SyntaxDocument that the control is currently attached to.")]
		public SyntaxDocument Document
		{
			get { return document; }
			set { this.AttachDocument(value); }
		}

		/// <summary>
		/// Gets or sets the delay before the tooltip is displayed over a collapsed code block.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets the delay before the tooltip is displayed over a collapsed code block.")]
		[DefaultValue(240)]
		public int TooltipDelay
		{
			get { return tooltipDelay; }
			set { tooltipDelay = value; }
		}

		/// <summary>
		/// Gets or sets whether the control is readonly.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets whether the control is readonly.")]
		[DefaultValue(false)]
		public bool ReadOnly
		{
			get { return readOnly; }
			set { readOnly = value; }
		}

		/// <summary>
		/// Gets or sets the name of the font of the control.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the name of the font of the control.")]
		[Editor(typeof(FontList), typeof(UITypeEditor))]
		[DefaultValue("Courier New")]
		public string FontName
		{
			get { return fontName; }
			set
			{
				if (this.Views == null)
					return;

				fontName = value;
				this.InitGraphics();
				foreach (TextEditorBase textEditorBase in this.Views)
					textEditorBase.CalculateMaxCharWidth();

				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the style to use when painting with Alt + (Arrow) keys.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets the style to use when painting with Alt + (Arrow) keys.")]
		[DefaultValue(TextDrawType.StarBorder)]
		public TextDrawType TextDrawStyle
		{
			get { return textDrawStyle; }
			set { textDrawStyle = value; }
		}

		/// <summary>
		/// Gets or sets whether bracket matching is enabled.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether bracket matching is enabled.")]
		[DefaultValue(true)]
		public bool BracketMatching
		{
			get { return bracketMatching; }
			set
			{
				bracketMatching = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether virtual whitespace is enabled.
		/// </summary>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets whether virtual whitespace is enabled.")]
		[DefaultValue(false)]
		public bool VirtualWhitespace
		{
			get { return virtualWhitespace; }
			set
			{
				virtualWhitespace = value;
				Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the separator color.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the separator color.")]
		[DefaultValue(typeof(Color), "Control")]
		public Color SeparatorColor
		{
			get { return separatorColor; }
			set
			{
				separatorColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the foreground color to use when BracketMatching equals true.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the foreground color to use when BracketMatching equals true.")]
		[DefaultValue(typeof(Color), "Black")]
		public Color BracketForeColor
		{
			get { return bracketForeColor; }
			set
			{
				bracketForeColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the background color to use when BracketMatching equals true.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the background color to use when BracketMatching equals true.")]
		[DefaultValue(typeof(Color), "LightSteelBlue")]
		public Color BracketBackColor
		{
			get { return bracketBackColor; }
			set
			{
				bracketBackColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the matching bracket should become bold when matched.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether the matching bracket should become bold when matched.")]
		public bool BracketBold
		{
			get { return bracketBold; }
			set
			{
				bracketBold = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the matching bracket should become italic when matched.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether the matching bracket should become italic when matched.")]
		public bool BracketItalic
		{
			get { return bracketItalic; }
			set
			{
				bracketItalic = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the matching bracket should become underlined when matched.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether the matching bracket should become underlined when matched.")]
		public bool BracketUnderline
		{
			get { return bracketUnderline; }
			set
			{
				bracketUnderline = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the matching bracket should become strikethroughed when matched.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether the matching bracket should become strikethroughed when matched.")]
		public bool BracketStrikethrough
		{
			get { return bracketStrikethrough; }
			set
			{
				bracketStrikethrough = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the background color of inactive selection areas.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the background color of inactive selection areas.")]
		public Color InactiveSelectionBackColor
		{
			get { return inactiveSelectionBackColor; }
			set
			{
				inactiveSelectionBackColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the border color of inactive selection areas.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the border color of inactive selection areas.")]
		public Color InactiveSelectionBorderColor
		{
			get { return inactiveSelectionBorderColor; }
			set
			{
				inactiveSelectionBorderColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the background color of active selection areas.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the background color of active selection areas.")]
		public Color SelectionBackColor
		{
			get { return selectionBackColor; }
			set
			{
				selectionBackColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the border color of active selection areas.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the border color of active selection areas.")]
		public Color SelectionBorderColor
		{
			get { return selectionBorderColor; }
			set
			{
				selectionBorderColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color of the border of the line number margin.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color of the border of the line number margin.")]
		public Color LineNumberBorderColor
		{
			get { return lineNumberBorderColor; }
			set
			{
				lineNumberBorderColor = value;
				this.InitGraphics();
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the foreground color of breakpoints.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the foreground color of breakpoints rows.")]
		public Color BreakpointForeColor
		{
			get { return breakpointForeColor; }
			set
			{
				breakpointForeColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the background color of the breakpoint rows.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the background color of the breakpoint rows.")]
		public Color BreakpointBackColor
		{
			get { return breakpointBackColor; }
			set
			{
				breakpointBackColor = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the foreground color of line numbers.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the foreground color of line numbers.")]
		public Color LineNumberForeColor
		{
			get { return lineNumberForeColor; }
			set
			{
				lineNumberForeColor = value;
				this.InitGraphics();
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the background color of line numbers.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the background color of line numbers.")]
		public Color LineNumberBackColor
		{
			get { return lineNumberBackColor; }
			set
			{
				lineNumberBackColor = value;
				this.InitGraphics();
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color of the gutter margin.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color of the gutter margin.")]
		public Color GutterMarginColor
		{
			get { return gutterMarginColor; }
			set
			{
				gutterMarginColor = value;
				this.InitGraphics();
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the background color of the client area.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the background color of the client area.")]
		new public Color BackColor
		{
			get { return backColor; }
			set
			{
				backColor = value;
				this.InitGraphics();
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the color of the highlighted line.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the color of the highlighted line.")]
		public Color HighlightedLineColor
		{
			get { return highlightedLineColor; }
			set
			{
				highlightedLineColor = value;
				this.InitGraphics();
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the line that the user is currently on should be highlighted.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether the line that the user is currently on should be highlighted.")]
		public bool HighlightActiveLine
		{
			get { return highlightActiveLine; }
			set
			{
				highlightActiveLine = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether whitespaces should be rendered as symbols.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether whitespaces should be rendered as symbols.")]
		public bool ShowWhitespace
		{
			get { return showWhitespace; }
			set
			{
				showWhitespace = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the line number margin should be visible.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether the line number margin should be visible.")]
		public bool ShowLineNumbers
		{
			get { return showLineNumbers; }
			set
			{
				showLineNumbers = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets whether the gutter margin should be visible.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether the gutter margin should be visible.")]
		public bool ShowGutterMargin
		{
			get { return showGutterMargin; }
			set
			{
				showGutterMargin = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets the width of the gutter margin.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the width of the gutter margin.")]
		public int GutterMarginWidth
		{
			get { return gutterMarginWidth; }
			set
			{
				gutterMarginWidth = value;
				this.Redraw();
			}

		}

		/// <summary>
		/// Gets or sets the size of a tab in number of whitespaces.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets the size of a tab in number of whitespaces.")]
		public int TabSpaces
		{
			get { return tabSize; }
			set
			{
				tabSize = value;
				this.Redraw();
			}
		}

		/// <summary>
		/// Gets or sets each of the ScrollBars' visibility.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets each of the ScrollBars' visibility.")]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public ScrollBars ScrollBars
		{
			get { return scrollBars; }

			set
			{
				if (this.Views == null)
					return;

				if (DisableScrollBars == true)
					value = ScrollBars.None;

				foreach (TextEditorBase textEditorBase in this.Views)
					textEditorBase.ScrollBars = value;

				scrollBars = value;
			}
		}

		/// <summary>
		/// Gets or sets whether the control should use SplitView controls.
		/// </summary>
		[Browsable(true)]
		[Category("Appearance")]
		[Description("Gets or sets whether the control should use SplitView controls.")]
		public bool SplitView
		{
			get { return splitView; }
			set
			{
				splitView = value;
				if (splitViewControl == null)
					return;

				if (this.SplitView == false)
				{
					splitViewControl.Visible = false;
					this.Controls.Add(lowerRight);

					lowerRight.HideThumbs();
					lowerRight.Dock = DockStyle.Fill;
				}
				else
				{
					splitViewControl.Visible = true;
					splitViewControl.LowerRight = lowerRight;

					lowerRight.Dock = DockStyle.None;
					lowerRight.ShowThumbs();
				}
			}
		}

		/// <summary>
		/// Gets or sets the text of the TextEditor.
		/// </summary>
		[Browsable(true)]
		[Category("Content")]
		[Description("Gets or sets the text of the TextEditor")]
		public override string Text
		{
			get { return ActiveViewControl.Document.Text; }
			set { ActiveViewControl.Document.Text = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the text editor automatically should detect what language to highlight.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if the text editor automatically should detect what language to highlight; otherwise, <c>false</c>.
		/// </value>
		[Browsable(true)]
		[Category("Behaviour")]
		[Description("Gets or sets a value indicating whether the text editor automatically should detect what language to highlight.")]
		public bool AutomaticLanguageDetection
		{
			get { return automaticLanguageDetection; }
			set
			{
				automaticLanguageDetection = value;
				if (automaticLanguageDetection == true)
					currentLanguage = XmlLanguage.None;
			}
		}

		/// <summary>
		/// Gets or sets the current highlighted language.
		/// </summary>
		/// <value>The current highlighted language.</value>
		[Browsable(true)]
		[Category("Content")]
		[Description("Gets or sets the current highlighted language.")]
		public XmlLanguage CurrentLanguage
		{
			get { return currentLanguage; }
			set
			{
				if (this.AutomaticLanguageDetection == true)
					return;

				currentLanguage = value;
				LanguageLoader.SetSyntax(this, currentLanguage);
			}
		}

		#endregion

		#region Methods

		#region Public

		#region File handling

		/// <summary>
		/// Saves the current file to the specified filename.
		/// </summary>
		/// <param name="filename">The filename.</param>
		public void Save(string filename)
		{
			string text = this.Document.Text;
			StreamWriter streamWriter = new StreamWriter(filename, false, Encoding.Unicode);

			streamWriter.Write(text);
			streamWriter.Flush();
			streamWriter.Close();

			this.DetectLanguage(filename);
			this.SetFileName(filename);
			this.Saved = true;
		}

		/// <summary>
		/// Saves the current file.
		/// </summary>
		public void Save()
		{
			if (this.FileName == null)
				throw new IOException("Invalid Filename.");

			this.Save(this.FileName);
		}

		/// <summary>
		/// Opens the file at the specified filename.
		/// </summary>
		/// <param name="filename">The filename.</param>
		public void Open(string filename)
		{
			if (this.Document == null)
				throw new NullReferenceException("TextEditor.Document");

			StreamReader streamReader = new StreamReader(filename);
			this.Text = streamReader.ReadToEnd();
			streamReader.Close();

			this.DetectLanguage(filename);
			this.SetFileName(filename);
			this.Saved = true;
		}

		/// <summary>
		/// Reloads the currently open file.
		/// </summary>
		public void ReloadFile()
		{
			if (this.FileName == null)
				throw new IOException("Invalid Filename.");

			this.Open(this.FileName);
		}

		/// <summary>
		/// Detects the language.
		/// </summary>
		/// <param name="filePath">The file path.</param>
		public void DetectLanguage(string filePath)
		{
			LanguageLoader.SetSyntax(this, XmlLanguage.None);	// Just for being sure.
			if (this.AutomaticLanguageDetection == true)
			{
				// Detect what language the text editor should be highlighting.
				foreach (List<string> fileExtensions in LanguageLoader.FoundLanguages.Keys)
				{
					foreach (string fileExtension in fileExtensions)
					{
						if (Path.GetExtension(filePath) == fileExtension)
						{
							// Check whether the enum of all known language contains the detected language.
							string languageNamespace = "Storm.TextEditor.Languages.";
							string languageFileName = LanguageLoader.FoundLanguages[fileExtensions] as string;
							XmlLanguage enumValue = XmlLanguage.Unknown;

							try
							{
								enumValue = (XmlLanguage)Enum.Parse(typeof(XmlLanguage), languageFileName.Remove
									(languageFileName.IndexOf(languageNamespace), languageNamespace.Length));
							}
							catch
							{
							}

							if (Enum.IsDefined(typeof(XmlLanguage), enumValue) == false)
								currentLanguage = XmlLanguage.Unknown;
							else
								currentLanguage = enumValue;

							LanguageLoader.SetSyntax(this, currentLanguage);

							break;
						}
					}
				}
			}
		}

		#endregion

		#region Document handling

		/// <summary>
		/// Attaches the document.
		/// </summary>
		/// <param name="document">The document.</param>
		public void AttachDocument(SyntaxDocument document)
		{
			if (this.document != null)
			{
				this.document.ParsingCompleted	-= this.OnParsingCompleted;
				this.document.Parsing			-= this.OnParse;
				this.document.Changed			-= this.OnChange;
			}

			if (document == null)
				document = new SyntaxDocument();

			this.document = document;

			if (this.document != null)
			{
				this.document.ParsingCompleted	+= this.OnParsingCompleted;
				this.document.Parsing			+= this.OnParse;
				this.document.Changed			+= this.OnChange;
			}

			this.Redraw();
		}

		#endregion

		#region Generic actions

		/// <summary>
		/// Clears the selection.
		/// </summary>
		public void ClearSelection()
		{
			activeView.ClearSelection();
		}

		/// <summary>
		/// Cuts and clears the current selection.
		/// </summary>
		public void CutClear()
		{
			activeView.CutClear();
		}

		/// <summary>
		/// Deletes the current selection.
		/// </summary>
		public void Delete()
		{
			activeView.Delete();
		}

		/// <summary>
		/// Copies the current selection.
		/// </summary>
		public void Copy()
		{
			activeView.Copy();
			this.Saved = false;
		}

		/// <summary>
		/// Cuts the current selection.
		/// </summary>
		public void Cut()
		{
			activeView.Cut();
			this.Saved = false;
		}

		/// <summary>
		/// Pastes the content of the clipboard to the text area.
		/// </summary>
		public void Paste()
		{
			activeView.Paste();
			this.Saved = false;
		}

		/// <summary>
		/// Redoes the last undone action by the user.
		/// </summary>
		public void Redo()
		{
			activeView.Redo();
			this.Saved = false;
		}

		/// <summary>
		/// Undoes the last action by the user.
		/// </summary>
		public void Undo()
		{
			activeView.Undo();
			this.Saved = false;
		}

		/// <summary>
		/// Selects all content of the text area.
		/// </summary>
		public void SelectAll()
		{
			activeView.SelectAll();
		}

		#endregion

		#region Row, Column and Line actions

		/// <summary>
		/// Removes the current row.
		/// </summary>
		public void RemoveCurrentRow()
		{
			activeView.RemoveCurrentRow();
		}

		/// <summary>
		/// If the caret is out of visibility, scrolls to it.
		/// </summary>
		public void ScrollIntoView()
		{
			activeView.ScrollIntoView();
		}

		/// <summary>
		/// Scrolls to the specified row.
		/// </summary>
		/// <param name="rowIndex">Row to scroll to.</param>
		public void ScrollIntoView(int rowIndex)
		{
			activeView.ScrollIntoView(rowIndex);
		}

		/// <summary>
		/// Scrolls to the specified text point.
		/// </summary>
		/// <param name="textPoint">Text point to scroll to.</param>
		public void ScrollIntoView(TextPoint textPoint)
		{
			activeView.ScrollIntoView(textPoint);
		}

		#endregion

		#region Goto actions

		/// <summary>
		/// Scrolls to the row at the given index.
		/// </summary>
		/// <param name="rowIndex">Index of the row.</param>
		public void GotoLine(int rowIndex)
		{ activeView.GotoLine(rowIndex); }

		/// <summary>
		/// Goes to the next bookmark.
		/// </summary>
		public void GotoNextBookmark()
		{
			activeView.GotoNextBookmark();
		}

		/// <summary>
		/// Goes to the previous bookmark.
		/// </summary>
		public void GotoPreviousBookmark()
		{
			activeView.GotoPreviousBookmark();
		}

		#endregion

		#region Find actions

		/// <summary>
		/// Finds the next match.
		/// </summary>
		public void FindNext()
		{
			activeView.FindNext();
		}

		/// <summary>
		/// Finds the next match.
		/// </summary>
		/// <param name="pattern">The pattern.</param>
		/// <param name="matchCase">if set to <c>true</c> [match case].</param>
		/// <param name="wholeWords">if set to <c>true</c> [whole words].</param>
		/// <param name="useRegex">if set to <c>true</c> [use regex].</param>
		public void FindNext(string pattern, bool matchCase, bool wholeWords, bool useRegex)
		{
			activeView.SelectNext(pattern, matchCase, wholeWords, useRegex);
		}

		#endregion

		#region Show actions

		/// <summary>
		/// Shows the find dialog.
		/// </summary>
		public void ShowFind()
		{
			activeView.ShowFind();
		}

		/// <summary>
		/// Shows the goto line dialog.
		/// </summary>
		public void ShowGotoLine()
		{
			activeView.ShowGotoLine();
		}

		/// <summary>
		/// Shows the replace dialog.
		/// </summary>
		public void ShowReplace()
		{
			activeView.ShowReplace();
		}

		#endregion

		#region Info actions

		/// <summary>
		/// Adds an info word.
		/// </summary>
		/// <param name="name">The name.</param>
		/// <param name="declaration">The declaration.</param>
		/// <param name="arguments">The arguments.</param>
		/// <param name="description">The description.</param>
		public void AddInfoWord(string name, string declaration, string arguments, string description)
		{
			if (wordDatabase.ContainsKey(name) == false)
				wordDatabase.Add(name, new WordData(name, description, declaration, arguments));
		}

		#endregion

		#region Other actions

		/// <summary>
		/// Gets the text point at the given coordinates.
		/// </summary>
		/// <param name="x">The x coordinate.</param>
		/// <param name="y">The y coordinate.</param>
		/// <returns>The found text point.</returns>
		public TextPoint GetTextPointAtPixel(int x, int y)
		{
			return activeView.GetTextPointAtPixel(x, y);
		}

		/// <summary>
		/// Determines whether the given coordinates are over the current selection.
		/// </summary>
		/// <param name="x">The x coordinate.</param>
		/// <param name="y">The y coordinate.</param>
		/// <returns>
		/// 	<c>true</c> if the given coordinates are over the selection; otherwise, <c>false</c>.
		/// </returns>
		public bool IsOverSelection(int x, int y)
		{
			return activeView.IsOverSelection(x, y);
		}

		/// <summary>
		/// Resets the splitview.
		/// </summary>
		public void ResetSplitview()
		{
			splitViewControl.ResetSplitview();
		}

		/// <summary>
		/// Toggles a bookmark at the line the user is currently on.
		/// </summary>
		public void ToggleBookmark()
		{
			activeView.ToggleBookmark();
		}

		/// <summary>
		/// Finds the languages.
		/// </summary>
		public void FindLanguages()
		{
            Hashtable globalLanguageExtensions = new Hashtable();
			string[] resourceFiles = typeof(LanguageLoader).Assembly.GetManifestResourceNames();
			foreach (string resourceFile in resourceFiles)
			{
				if (Path.GetExtension(resourceFile) == LanguageLoader.XmlLanguageFileExtension)
				{
					Stream resourceStream = typeof(LanguageLoader).Assembly.GetManifestResourceStream(resourceFile);
					if (resourceStream != null)
					{
						// Find the extensions that are included in the language definition files.
						Language resourceLanguage = Language.FromSyntaxFile(resourceStream);
						List<string> languageExtensions = new List<string>();

						// Make sure the language actually is parsed by the LanguageReader.
						LanguageLoader.SetSyntax(this, resourceFile);

						bool addLanguageDialogFilters = true;
                        foreach (object fileType in resourceLanguage.FileTypes)
                        {
                            addLanguageDialogFilters = globalLanguageExtensions.Contains((fileType as FileType).Extension) == false;

                            if (fileType is FileType)
                            {
                                languageExtensions.Add((fileType as FileType).Extension);

                                if (globalLanguageExtensions.Contains((fileType as FileType).Extension) == false)
                                    globalLanguageExtensions.Add((fileType as FileType).Extension, resourceLanguage);
                            }

                            if (addLanguageDialogFilters == false)
                            {
                                Language language = globalLanguageExtensions[(fileType as FileType).Extension] as Language;

                                languageExtensions.Remove((fileType as FileType).Extension);
                                globalLanguageExtensions.Remove((fileType as FileType).Extension);

                                language.FileTypes.Remove(fileType);
                            }
                        }

						// Add the found extensions along with the name of the language.
						LanguageLoader.FoundLanguages.Add(languageExtensions, Path.GetFileNameWithoutExtension(resourceFile));
                        addLanguageDialogFilters = addLanguageDialogFilters == true && LanguageLoader.DialogFilter.Contains(resourceLanguage.FileDialogFilters) == false;

						if (addLanguageDialogFilters == true)
						{
							// Add the found language's extensions to the LanguageLoader's DialogFilter property.
							LanguageLoader.DialogFilter += resourceLanguage.FileDialogFilters;
						}
					}
				}
			}

			// Remove the last added "|" from the LanguageLoader's DialogFilter property.
			LanguageLoader.DialogFilter = LanguageLoader.DialogFilter.Substring(0, LanguageLoader.DialogFilter.Length - 1);
		}

		#endregion

		#endregion

		#region Private

		#region Info Methods

		/// <summary>
		/// Called when [mouse word hover].
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.WordMouseEventArgs"/> instance containing the event data.</param>
		private void OnMouseWordHover(object sender, ref WordMouseEventArgs e)
		{
			string word = e.Word.Text.Trim();
			if (wordDatabase.ContainsKey(word) == true)
			{
				if (tooltipShown == true)
					return;

				Point tooltipPosition = this.PointToClient(new Point(Cursor.Position.X + 10, Cursor.Position.Y + 10));
				tooltip.Show(wordDatabase[word].Declaration + "\n" + wordDatabase[word].Description, this, tooltipPosition.X, 
					tooltipPosition.Y, 60000);

				tooltipShown = true;
			}
			else if (tooltipShown == true)
			{
				tooltipShown = false;
				tooltip.Hide(this);
			}
		}

		#endregion

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			components = new Container();
			ComponentResourceManager resources = new ComponentResourceManager(typeof(TextEditor));
			gutterIcons = new ImageList(components);
			parseTimer = new WeakTimer(components);
			this.SuspendLayout();

			gutterIcons.ImageStream = ((ImageListStreamer)(resources.GetObject("_gutterIcons.ImageStream")));
			gutterIcons.TransparentColor = Color.Fuchsia;
			gutterIcons.Images.SetKeyName(0, "break_point.png");
			gutterIcons.Images.SetKeyName(1, "BookMarkForGuttor.bmp");

			parseTimer.Enabled = true;
			parseTimer.Interval = 1;
			parseTimer.Tick += OnParseTimerTick;
			this.ResumeLayout(false);
		}

		/// <summary>
		/// Sets the current filename.
		/// </summary>
		/// <param name="filename">The filename.</param>
		private void SetFileName(string filename)
		{
			fileName = filename;
			this.OnFileNameChanged(new EventArgs());
		}

		/// <summary>
		/// Activates the split views.
		/// </summary>
		private void ActivateSplits()
		{
			if (upperLeft == null)
			{
				upperLeft	= new TextEditorBase(this);
				upperRight = new TextEditorBase(this);
				lowerLeft	= new TextEditorBase(this);

				upperLeft.AllowDrop = true;
				upperLeft.Name = "_upperLeft";
				upperLeft.TabIndex = 6;

				upperRight.AllowDrop = true;
				upperRight.Name = "_upperRight";
				upperRight.TabIndex = 4;

				lowerLeft.AllowDrop = true;
				lowerLeft.Name = "_lowerLeft";
				lowerLeft.TabIndex = 5;

				splitViewControl.Controls.AddRange(new Control[]
					{
						upperLeft,
						lowerLeft,
						upperRight
					});

				splitViewControl.UpperRight = lowerLeft;
				splitViewControl.UpperLeft = upperLeft;
				splitViewControl.LowerLeft = upperRight;

				this.CreateViews();

				// Update the TextEditor properties to redraw it.
				this.ChildBorderStyle = this.ChildBorderStyle;
				this.ChildBorderColor = this.ChildBorderColor;
				this.BackColor = this.BackColor;
				this.Document = this.Document;
				this.Redraw();
			}
		}

		/// <summary>
		/// Redraws this instance.
		/// </summary>
		private void Redraw()
		{
			if (this.Views == null)
				return;

			foreach (TextEditorBase textEditorBase in this.Views)
			{
				if (textEditorBase != null)
					textEditorBase.Refresh();
			}
		}

		/// <summary>
		/// Initializes the graphics.
		/// </summary>
		private void InitGraphics()
		{
			if (this.Views == null || this.Parent == null)
				return;

			foreach (TextEditorBase textEditorBase in this.Views)
				textEditorBase.InitGraphics();
		}

		/// <summary>
		/// Creates the views.
		/// </summary>
		private void CreateViews()
		{
			if (upperRight != null)
			{
				this.Views.Add(upperRight);
				this.Views.Add(upperLeft);
				this.Views.Add(lowerLeft);
			}

			if (createdSplitViews == false)
			{
				this.Views.Add(lowerRight);

				lowerRight.TopThumbVisible  = true;
				lowerRight.LeftThumbVisible = true;


				lowerRight.TopThumb.MouseDown	+= OnTopThumbMouseDown;
				lowerRight.LeftThumb.MouseDown	+= OnLeftThumbMouseDown;
			}

			foreach (TextEditorBase textEditorBase in this.Views)
			{
				if (createdSplitViews == true && textEditorBase == lowerRight)
					continue;

				textEditorBase.Enter			+= OnViewEnter;
				textEditorBase.GotFocus			+= OnViewEnter;
				textEditorBase.CaretChange		+= OnViewCaretChanged;
				textEditorBase.SelectionChange	+= OnViewSelectionChanged;
				textEditorBase.Click			+= OnViewClick;
				textEditorBase.DoubleClick		+= OnViewDoubleClick;
				textEditorBase.MouseDown		+= OnViewMouseDown;
				textEditorBase.MouseEnter		+= OnViewMouseEnter;
				textEditorBase.MouseHover		+= OnViewMouseHover;
				textEditorBase.MouseLeave		+= OnViewMouseLeave;
				textEditorBase.MouseMove		+= OnViewMouseMove;
				textEditorBase.MouseUp			+= OnViewMouseUp;
				textEditorBase.KeyDown			+= OnViewKeyDown;
				textEditorBase.KeyPress			+= OnViewKeyPress;
				textEditorBase.KeyUp			+= OnViewKeyUp;
				textEditorBase.DragDrop			+= OnViewDragDrop;
				textEditorBase.DragOver			+= OnViewDragOver;
				textEditorBase.DragLeave		+= OnViewDragLeave;
				textEditorBase.DragEnter		+= OnViewDragEnter;

				textEditorBase.RowClick			+= OnViewRowClick;
				textEditorBase.RowDoubleClick	+= OnViewRowDoubleClick;

				textEditorBase.RowMouseDown		+= OnViewRowMouseDown;
				textEditorBase.RowMouseMove		+= OnViewRowMouseMove;
				textEditorBase.RowMouseUp		+= OnViewRowMouseUp;
				textEditorBase.ClipboardUpdated += OnViewClipboardUpdated;
			}

			createdSplitViews = true;
			this.Redraw();
		}

		#endregion

		#region Protected

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing"></param>
		protected override void Dispose(bool disposing)
		{
			if (disposing == true)
			{
				if (components != null)
					components.Dispose();
			}

			base.Dispose(disposing);
		}

		/// <summary>
		/// Raises the <see cref="E:FileNameChanged"/> event.
		/// </summary>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		protected virtual void OnFileNameChanged(EventArgs e)
		{
			if (this.FileNameChanged != null)
				this.FileNameChanged(null, e);
		}

		/// <summary>
		/// Raises the <see cref="E:FileSavedChanged"/> event.
		/// </summary>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		protected virtual void OnFileSavedChanged(EventArgs e)
		{
			if (this.FileSavedChanged != null)
				this.FileSavedChanged(this, e);
		}

		/// <summary>
		/// Raises the Load event.
		/// </summary>
		/// <param name="e">EventArgs.</param>
		protected override void OnLoad(EventArgs e)
		{
			this.Refresh();
			base.OnLoad(e);
		}

		/// <summary>
		/// Processes Windows messages from the OS.
		/// </summary>
		/// <param name="m">Windows message to process.</param>
		protected override void WndProc(ref Message m)
		{
			base.WndProc(ref m);
			if (m.Msg == (int)WindowMessage.WM_SETFOCUS)
			{
				if (activeView != null)
					activeView.Focus();
			}
		}

		/// <summary>
		/// Called when [parse].
		/// </summary>
		/// <param name="ssender">The sender.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		protected virtual void OnParse(object sender, EventArgs e)
		{
			foreach (TextEditorBase textEditorBase in this.Views)
				textEditorBase.OnParse();
		}

		/// <summary>
		/// Called when [parsing completed].
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		protected virtual void OnParsingCompleted(object sender, EventArgs e)
		{
			foreach (TextEditorBase textEditorBase in this.Views)
				textEditorBase.Invalidate();
		}

		/// <summary>
		/// Called when [change].
		/// </summary>
		/// <param name="Sender">The sender.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		protected virtual void OnChange(object sender, EventArgs e)
		{
			if (this.Views == null)
				return;

			foreach (TextEditorBase textEditorBase in this.Views)
				textEditorBase.OnChange();

			this.OnTextChanged(EventArgs.Empty);
		}

		#endregion

		#region EventHandlers

		/// <summary>
		/// Raises the <see cref="E:ClipboardUpdated"/> event.
		/// </summary>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.CopyEventArgs"/> instance containing the event data.</param>
		protected virtual void OnClipboardUpdated(CopyEventArgs e)
		{
			if (this.ClipboardUpdated != null)
				this.ClipboardUpdated(this, e);
		}

		/// <summary>
		/// Raises the <see cref="E:RowMouseDown"/> event.
		/// </summary>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		protected virtual void OnRowMouseDown(RowMouseEventArgs e)
		{
			if (this.RowMouseDown != null)
				this.RowMouseDown(this, e);
		}

		/// <summary>
		/// Raises the <see cref="E:RowMouseMove"/> event.
		/// </summary>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		protected virtual void OnRowMouseMove(RowMouseEventArgs e)
		{
			if (this.RowMouseMove != null)
				this.RowMouseMove(this, e);
		}

		/// <summary>
		/// Raises the <see cref="E:RowMouseUp"/> event.
		/// </summary>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		protected virtual void OnRowMouseUp(RowMouseEventArgs e)
		{
			if (this.RowMouseUp != null)
				this.RowMouseUp(this, e);
		}

		/// <summary>
		/// Raises the <see cref="E:RowClick"/> event.
		/// </summary>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		protected virtual void OnRowClick(RowMouseEventArgs e)
		{
			if (this.RowClick != null)
				this.RowClick(this, e);
		}

		/// <summary>
		/// Raises the <see cref="E:RowDoubleClick"/> event.
		/// </summary>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		protected virtual void OnRowDoubleClick(RowMouseEventArgs e)
		{
			if (this.RowDoubleClick != null)
				this.RowDoubleClick(this, e);
		}

		/// <summary>
		/// Handles the Tick event of the parseTimer control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnParseTimerTick(object sender, EventArgs e)
		{
			this.Document.ParseSome();
		}

		/// <summary>
		/// Raises the <see cref="E:System.Windows.Forms.Control.Enter"/> event.
		/// </summary>
		/// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
		protected override void OnEnter(EventArgs e)
		{
			base.OnEnter(e);
			if (activeView != null)
				activeView.Focus();
		}

		/// <summary>
		/// Handles the MouseDown event of the TopThumb control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
		private void OnTopThumbMouseDown(object sender, MouseEventArgs e)
		{
			this.ActivateSplits();
			long ticks = DateTime.Now.Ticks - this.ticks;
			this.ticks = DateTime.Now.Ticks;

			if (ticks < 3000000)
				splitViewControl.SplitHorizontalHalf();
			else
				splitViewControl.InvokeMouseDownHorizontal();
		}

		/// <summary>
		/// Handles the MouseDown event of the LeftThumb control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
		private void OnLeftThumbMouseDown(object sender, MouseEventArgs e)
		{
			this.ActivateSplits();
			long ticks = DateTime.Now.Ticks - this.ticks;
			this.ticks = DateTime.Now.Ticks;

			if (ticks < 3000000)
				splitViewControl.SplitVerticalHalf();
			else
				splitViewControl.InvokeMouseDownVertical();
		}

		/// <summary>
		/// Handles the Resizing event of the split views.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnSplitViewResizing(object sender, EventArgs e)
		{
			lowerRight.TopThumbVisible = false;
			lowerRight.LeftThumbVisible = false;
		}

		/// <summary>
		/// Handles the HideTop event of the split views.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnSplitViewHideTop(object sender, EventArgs e)
		{
			lowerRight.TopThumbVisible = true;
		}

		/// <summary>
		/// Handles the HideLeft event of the split views.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnSplitViewHideLeft(object sender, EventArgs e)
		{
			lowerRight.LeftThumbVisible = true;
		}

		/// <summary>
		/// Raises the <see cref="E:RenderRow"/> event.
		/// </summary>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowPaintEventArgs"/> instance containing the event data.</param>
		public void OnRenderRow(RowPaintEventArgs e)
		{
			if (this.RenderRow != null)
				this.RenderRow(this, e);
		}

		/// <summary>
		/// Raises the <see cref="E:WordMouseHover"/> event.
		/// </summary>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.WordMouseEventArgs"/> instance containing the event data.</param>
		public void OnWordMouseHover(ref WordMouseEventArgs e)
		{
			if (this.WordMouseHover != null)
				this.WordMouseHover(this, ref e);

			this.OnMouseWordHover(this, ref e);
		}

		/// <summary>
		/// Raises the <see cref="E:WordMouseDown"/> event.
		/// </summary>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.WordMouseEventArgs"/> instance containing the event data.</param>
		public void OnWordMouseDown(ref WordMouseEventArgs e)
		{
			if (this.WordMouseDown != null)
				this.WordMouseDown(this, ref e);
		}

		/// <summary>
		/// Called when [caret change].
		/// </summary>
		/// <param name="sender">The sender.</param>
		protected virtual void OnCaretChange(object sender)
		{
			if (this.CaretChange != null)
				this.CaretChange(this, null);
		}

		/// <summary>
		/// Called when [selection change].
		/// </summary>
		/// <param name="sender">The sender.</param>
		protected virtual void OnSelectionChange(object sender)
		{
			if (this.SelectionChange != null)
				this.SelectionChange(this, null);
		}

		/// <summary>
		/// Handles the Enter event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnViewEnter(object sender, EventArgs e)
		{
			activeView = sender as TextEditorBase;
		}

		/// <summary>
		/// Handles the RowClick event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		private void OnViewRowClick(object sender, RowMouseEventArgs e)
		{
			this.OnRowClick(e);
		}

		/// <summary>
		/// Handles the RowDoubleClick event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		private void OnViewRowDoubleClick(object sender, RowMouseEventArgs e)
		{
			this.OnRowDoubleClick(e);
		}

		/// <summary>
		/// Handles the RowMouseDown event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		private void OnViewRowMouseDown(object sender, RowMouseEventArgs e)
		{
			this.OnRowMouseDown(e);
		}

		/// <summary>
		/// Handles the RowMouseMove event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		private void OnViewRowMouseMove(object sender, RowMouseEventArgs e)
		{
			this.OnRowMouseMove(e);
		}

		/// <summary>
		/// Handles the RowMouseUp event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.RowMouseEventArgs"/> instance containing the event data.</param>
		private void OnViewRowMouseUp(object sender, RowMouseEventArgs e)
		{
			this.OnRowMouseUp(e);
		}

		/// <summary>
		/// Handles the ClipboardUpdated event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="Storm.TextEditor.Editor.CopyEventArgs"/> instance containing the event data.</param>
		private void OnViewClipboardUpdated(object sender, CopyEventArgs e)
		{
			this.OnClipboardUpdated(e);
		}

		/// <summary>
		/// Handles the CaretChanged event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnViewCaretChanged(object sender, EventArgs e)
		{
			this.OnCaretChange(sender);
		}

		/// <summary>
		/// Handles the SelectionChanged event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnViewSelectionChanged(object sender, EventArgs e)
		{
			this.OnSelectionChange(sender);
		}

		/// <summary>
		/// Handles the DoubleClick event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnViewDoubleClick(object sender, EventArgs e)
		{
			this.OnDoubleClick(e);
		}

		/// <summary>
		/// Handles the MouseUp event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
		private void OnViewMouseUp(object sender, MouseEventArgs e)
		{
			TextEditorBase textEditorBase = (TextEditorBase)sender;
			MouseEventArgs eventArgs = new MouseEventArgs(e.Button, e.Clicks, e.X + textEditorBase.Location.X + textEditorBase.BorderWidth, 
				e.Y + textEditorBase.Location.Y + textEditorBase.BorderWidth, e.Delta);

			this.OnMouseUp(eventArgs);
		}

		/// <summary>
		/// Handles the MouseMove event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
		private void OnViewMouseMove(object sender, MouseEventArgs e)
		{
			TextEditorBase textEditorBase = (TextEditorBase)sender;
			MouseEventArgs eventArgs = new MouseEventArgs(e.Button, e.Clicks, e.X + textEditorBase.Location.X + textEditorBase.BorderWidth, 
				e.Y + textEditorBase.Location.Y + textEditorBase.BorderWidth, e.Delta);

			this.OnMouseMove(eventArgs);
		}

		/// <summary>
		/// Handles the MouseLeave event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnViewMouseLeave(object sender, EventArgs e)
		{
			this.OnMouseLeave(e);
		}

		/// <summary>
		/// Handles the MouseHover event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnViewMouseHover(object sender, EventArgs e)
		{
			this.OnMouseHover(e);
		}

		/// <summary>
		/// Handles the MouseEnter event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnViewMouseEnter(object sender, EventArgs e)
		{
			this.OnMouseEnter(e);
		}

		/// <summary>
		/// Handles the MouseDown event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
		private void OnViewMouseDown(object sender, MouseEventArgs e)
		{
			TextEditorBase textEditorBase = sender as TextEditorBase;
			MouseEventArgs eventArgs = new MouseEventArgs(e.Button, e.Clicks, e.X + textEditorBase.Location.X + textEditorBase.BorderWidth, 
				e.Y + textEditorBase.Location.Y + textEditorBase.BorderWidth, e.Delta);

			this.OnMouseDown(eventArgs);
		}

		/// <summary>
		/// Handles the KeyUp event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.KeyEventArgs"/> instance containing the event data.</param>
		private void OnViewKeyUp(object sender, KeyEventArgs e)
		{
			this.OnKeyUp(e);
			this.Saved = false;
		}

		/// <summary>
		/// Handles the KeyPress event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.KeyPressEventArgs"/> instance containing the event data.</param>
		private void OnViewKeyPress(object sender, KeyPressEventArgs e)
		{
			this.OnKeyPress(e);
		}

		/// <summary>
		/// Handles the KeyDown event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.KeyEventArgs"/> instance containing the event data.</param>
		private void OnViewKeyDown(object sender, KeyEventArgs e)
		{
			this.OnKeyDown(e);
		}

		/// <summary>
		/// Handles the Click event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnViewClick(object sender, EventArgs e)
		{
			this.OnClick(e);
		}

		/// <summary>
		/// Handles the DragOver event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.DragEventArgs"/> instance containing the event data.</param>
		private void OnViewDragOver(object sender, DragEventArgs e)
		{
			this.OnDragOver(e);
		}

		/// <summary>
		/// Handles the DragLeave event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void OnViewDragLeave(object sender, EventArgs e)
		{
			this.OnDragLeave(e);
		}

		/// <summary>
		/// Handles the DragEnter event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.DragEventArgs"/> instance containing the event data.</param>
		private void OnViewDragEnter(object sender, DragEventArgs e)
		{
			this.OnDragEnter(e);
		}

		/// <summary>
		/// Handles the DragDrop event of a view.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.DragEventArgs"/> instance containing the event data.</param>
		private void OnViewDragDrop(object sender, DragEventArgs e)
		{
			this.OnDragDrop(e);
			this.Saved = false;
		}

		#endregion

		#endregion

		/// <summary>
		/// Initializes a new instance of the <see cref="TextEditor"/> class.
		/// </summary>
		public TextEditor()
			: base()
		{
			this.Document = new SyntaxDocument();
			this.Document.Folding = true;

			if (DisableSplitView == false)
			{
				splitViewControl = new SplitViewControl();
				lowerRight = new TextEditorBase(this);
			}
			else
			{
				lowerRight = new TextEditorBase(this);
				this.Controls.Add(lowerRight);

				lowerRight.HideThumbs();
				lowerRight.Dock = DockStyle.Fill;
			}

			this.SuspendLayout();
			if (DisableSplitView == false)
			{
				splitViewControl.SuspendLayout();
				splitViewControl.BackColor = SystemColors.Control;
				splitViewControl.Controls.Add(lowerRight);
				splitViewControl.Dock = DockStyle.Fill;
				splitViewControl.Location = new Point(0, 0);
				splitViewControl.LowerRight = lowerRight;
				splitViewControl.Name = "splitView";
				splitViewControl.Size = new Size(500, 364);
				splitViewControl.TabIndex = 0;
			}

			lowerRight.AllowDrop = true;
			lowerRight.BorderColor = Color.White;
			lowerRight.BorderStyle = ControlBorderStyle.None;
			lowerRight.Location = new Point(148, 124);
			lowerRight.Name = "_lowerRight";
			lowerRight.Size = new Size(352, 240);
			lowerRight.TabIndex = 3;
			lowerRight.TextDrawStyle = TextDrawType.StarBorder;

			if (DisableSplitView == false)
				this.Controls.Add(splitViewControl);

			tooltip = new ToolTip();

			this.Name = "TextEditor";
			this.Size = new Size(504, 368);
			if (DisableSplitView == false)
			{
				splitViewControl.ResumeLayout(false);
				splitViewControl.Resizing += new EventHandler(OnSplitViewResizing);
				splitViewControl.HideLeft += new EventHandler(OnSplitViewHideLeft);
				splitViewControl.HideTop += new EventHandler(OnSplitViewHideTop);
			}

			this.ResumeLayout(false);

			this.Views = new ArrayList();
			this.CreateViews();

			activeView = lowerRight;

			this.FindLanguages();

			// Required by the Windows Forms Designer.
			InitializeComponent();

			this.SetStyle(ControlStyles.Selectable, true);
			this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
			this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
			this.SetStyle(ControlStyles.UserPaint, true);

			this.KeyboardActions.Add(new KeyboardAction(Keys.Z, false, true, false, false,		new ActionDelegate(this.Undo)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.Y, false, true, false, false,		new ActionDelegate(this.Redo)));

			this.KeyboardActions.Add(new KeyboardAction(Keys.F3, false, false, false, true,		new ActionDelegate(this.FindNext)));

			this.KeyboardActions.Add(new KeyboardAction(Keys.C, false, true, false, true,		new ActionDelegate(this.Copy)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.X, false, true, false, false,		new ActionDelegate(this.CutClear)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.V, false, true, false, false,		new ActionDelegate(this.Paste)));

			this.KeyboardActions.Add(new KeyboardAction(Keys.Insert, false, true, false, true,	new ActionDelegate(this.Copy)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.Delete, true, false, false, false, new ActionDelegate(this.Cut)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.Insert, true, false, false, false, new ActionDelegate(this.Paste)));

			this.KeyboardActions.Add(new KeyboardAction(Keys.A, false, true, false, true,		new ActionDelegate(this.SelectAll)));

			this.KeyboardActions.Add(new KeyboardAction(Keys.F, false, true, false, false,		new ActionDelegate(this.ShowFind)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.H, false, true, false, false,		new ActionDelegate(this.ShowReplace)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.G, false, true, false, true,		new ActionDelegate(this.ShowGotoLine)));

			this.KeyboardActions.Add(new KeyboardAction(Keys.F2, false, true, false, true,		new ActionDelegate(this.ToggleBookmark)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.F2, false, false, false, true,		new ActionDelegate(this.GotoNextBookmark)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.F2, true, false, false, true,		new ActionDelegate(this.GotoPreviousBookmark)));

			this.KeyboardActions.Add(new KeyboardAction(Keys.Escape, false, false, false, true, new ActionDelegate(this.ClearSelection)));

			this.KeyboardActions.Add(new KeyboardAction(Keys.Tab, false, false, false, false,	new ActionDelegate(this.Selection.Indent)));
			this.KeyboardActions.Add(new KeyboardAction(Keys.Tab, true, false, false, false,	new ActionDelegate(this.Selection.Outdent)));

			this.SplitView   = true;
			this.ScrollBars  = ScrollBars.Both;
			this.BorderStyle = ControlBorderStyle.None;

			this.ChildBorderColor = SystemColors.ControlDark;
			this.ChildBorderStyle = ControlBorderStyle.FixedSingle;

			this.BackColor = SystemColors.Window;
		}
	}
}
